/*
 * @(#)XfdmIncGridDialog.java        1.0 2000/05/09
 *
 * This file is part of Xfuzzy 3.0, a design environment for fuzzy logic
 * based systems.
 *
 * (c) 2000 IMSE-CNM. The authors may be contacted by the email address:
 *                    xfuzzy-team@imse.cnm.es
 *
 * Xfuzzy is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation.
 *
 * Xfuzzy is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 */


package xfuzzy.xfdm.view;

import xfuzzy.util.*;
import xfuzzy.xfdm.model.XfdmAlgorithm;
import xfuzzy.xfdm.model.algorithm.XfdmIncGrid;
import xfuzzy.xfdm.view.listener.*;
import javax.swing.*;
import java.awt.*;

/**
 * Ventana de configuraci�n del algoritmo de grid incremental
 * 
 * @author Francisco Jos� Moreno Velo
 *
 */
public class XfdmIncGridDialog extends JDialog implements IXfdmAlgorithmDialog, IXfdmFrame {

	/**
	 * C�digo asociado a la clase serializable
	 */
	private static final long serialVersionUID = 95505666603014L;

	//----------------------------------------------------------------------------//
	//                            MIEMBROS PRIVADOS                               //
	//----------------------------------------------------------------------------//

	/**
	 * Algoritmo a configurar
	 */
	private XfdmIncGrid algorithm;
	
	/**
	 * Campos para introducir los valores de configuraci�n
	 */
	private XTextField[] text;
	
	/**
	 * Bot�n de la opci�n de aprendizaje
	 */
	private JRadioButton learning;
	
	/**
	 * Marcador de configuraci�n realizada 
	 */
	private boolean conf;

	//----------------------------------------------------------------------------//
	//                               CONSTRUCTOR                                  //
	//----------------------------------------------------------------------------//

	/**
	 * Constructor
	 */
	public XfdmIncGridDialog(Xfdm xfdm, XfdmAlgorithm alg){
		super(xfdm,"Xfdm",true);
		if(alg != null && alg instanceof XfdmIncGrid) {
			this.algorithm = (XfdmIncGrid) ((XfdmIncGrid) alg).clone();
		} else {
			this.algorithm = new XfdmIncGrid();
		}
		build();
		set();
	}

	//----------------------------------------------------------------------------//
	//                             M�TODOS P�BLICOS                               //
	//----------------------------------------------------------------------------//

	/**
	 * Muestra el di�logo
	 */
	public static XfdmIncGrid showDialog(Xfdm xfdm, XfdmAlgorithm algorithm) {
		XfdmIncGridDialog dialog = new XfdmIncGridDialog(xfdm, algorithm);
		dialog.setVisible(true);
		return dialog.getAlgorithm();
	}

	/**
	 * Obtiene el algoritmo
	 */
	public XfdmIncGrid getAlgorithm() {
		if(this.conf) return this.algorithm;
		return null;
	}

	/**
	 * Acci�n de almacenar los datos y cerrar la ventana
	 */
	public void actionSet() {
		try { get(); } catch(Exception ex) { return; }
		this.conf = true;
		setVisible(false); 
	}

	/**
	 * Acci�n de cerrar la ventana 
	 */
	public void actionCancel() {
		this.conf = false;
		setVisible(false); 
	}

	/**
	 * Acci�n de cerrar la ventana 
	 */
	public void close() {
		this.conf = false;
		setVisible(false); 
	}
	
	//----------------------------------------------------------------------------//
	//                             M�TODOS PRIVADOS                               //
	//----------------------------------------------------------------------------//

	/**
	 * Generaci�n de la ventana
	 */
	private void build() {
		String lb[] = {"Set", "Cancel"};
		XCommandForm form = new XCommandForm(lb,lb,new XfdmAlgorithmActionListener(this));
		form.setCommandWidth(150);
		form.block();

		text = new XTextField[3];
		text[0] = new XTextField("");
		text[1] = new XTextField("");
		text[2] = new XTextField("");

		learning = new JRadioButton("Activate");

		Box box = new Box(BoxLayout.X_AXIS);
		box.add(Box.createHorizontalStrut(20));
		box.add(learning);

		JPanel lpanel = new JPanel();
		lpanel.setLayout(new GridLayout(4,2));
		lpanel.add(new XLabel("Limit of MFs"));
		lpanel.add(text[0]);
		lpanel.add(new XLabel("Limit of Rules"));
		lpanel.add(text[1]);
		lpanel.add(new XLabel("Limit of RMSE"));
		lpanel.add(text[2]);
		lpanel.add(new XLabel("Learning option"));
		lpanel.add(box);

		Container content = getContentPane();
		content.setLayout(new BoxLayout(content,BoxLayout.Y_AXIS));
		content.add(new XLabel("Parameter selection for Incremental Grid algorithm"));
		content.add(Box.createVerticalStrut(5));
		content.add(lpanel);
		content.add(Box.createVerticalStrut(5));
		content.add(form);

		setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
		addWindowListener(new XfdmWindowListener(this));
		pack();
		setLocation();
	}

	/**
	 * Coloca la ventana en la pantalla	
	 */
	private void setLocation() {
		Dimension frame = getSize();
		Dimension screen = getToolkit().getScreenSize();
		setLocation((screen.width - frame.width)/2,(screen.height - frame.height)/2);
	}

	/**
	 * Actualiza los par�metros de configuraci�n del algoritmo
	 */
	private void set() {
		int mfs = algorithm.getMfsLimit();
		int rule = algorithm.getRuleLimit();
		double rmse = algorithm.getRMSELimit();
		if(mfs>0) text[0].setText(""+mfs); else text[0].setText("");
		if(rule>0) text[1].setText(""+rule); else text[1].setText("");
		if(rmse>0) text[2].setText(""+rmse); else text[2].setText("");
		learning.setSelected(algorithm.isLearning());
	}

	/**
	 * Detecta posibles errores en los valores de los par�metros
	 */
	private boolean get() {
		boolean error = false;
		int mfs = -1;
		int rule = -1;
		double rmse = -1;
		if(text[0].getText().trim().length() > 0) {
			try { mfs = Integer.parseInt(text[0].getText().trim()); }
			catch(Exception ex) { error = true; text[0].setText(""); }
		}
		if(text[1].getText().trim().length() > 0) {
			try { rule = Integer.parseInt(text[1].getText().trim()); }
			catch(Exception ex) { error = true; text[1].setText(""); }
		}
		if(text[2].getText().trim().length() > 0) {
			try { rmse = Double.parseDouble(text[2].getText().trim()); }
			catch(Exception ex) { error = true; text[2].setText(""); }
		}
		if(mfs != -1 && mfs <= 0) error = true;
		if(rule != -1 && rule <= 0) error = true;
		if(rmse != -1 && (rmse <= 0.0 || rmse >= 1.0)) error = true;

		if(error) {
			XDialog.showMessage(text[0],"Not a valid value");
			return false;
		}
		if(mfs == -1 && rule == -1 && rmse == -1) {
			XDialog.showMessage(text[0],"An end condition is needed");
			return false;
		}

		algorithm.setMfsLimit(mfs);
		algorithm.setRuleLimit(rule);
		algorithm.setRMSELimit(rmse);
		algorithm.setLearning(learning.isSelected());
		return true;
	}

}


